using System;
using System.Reflection;
using RemoteLoader;

namespace RemoteLoader
{
	/// <summary>
	/// Factory class to create objects exposing IRemoteInterface
	/// </summary>
	public class RemoteLoaderFactory : MarshalByRefObject
	{
		private const BindingFlags bfi = BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance;

		public RemoteLoaderFactory() {}

		/// <summary> Factory method to create an instance of the type whose name is specified,
		/// using the named assembly file and the constructor that best matches the specified parameters. </summary>
		/// <param name="assemblyFile"> The name of a file that contains an assembly where the type named typeName is sought. </param>
		/// <param name="typeName"> The name of the preferred type. </param>
		/// <param name="constructArgs"> An array of arguments that match in number, order, and type the parameters of the constructor to invoke, or null for default constructor. </param>
		/// <returns> The return value is the created object represented as ILiveInterface. </returns>
		public IRemoteInterface Create( string assemblyFile, string typeName, object[] constructArgs )
		{
			return (IRemoteInterface) Activator.CreateInstanceFrom(
				assemblyFile, typeName, false, bfi, null, constructArgs,
				null, null, null ).Unwrap();
		}

        public string GetAssemblyName(string assemblyFile)
        {
            try
            {
                Assembly ass = Assembly.LoadFile(assemblyFile);

                return ass.FullName;
            }
            catch
            {
            }

            return null;
        }

        /// <summary>
        /// Does Assembly Contain A Class That Is A SubClass of type name
        /// </summary>
        /// <param name="assemblyFile"></param>
        /// <param name="typeName"></param>
        /// <returns></returns>
        public bool IsSubclassOfCodeDomProvider(string assemblyFile)
        {
            try
            {
                Type basetype = typeof(System.CodeDom.Compiler.CodeDomProvider);

                Assembly ass = Assembly.LoadFile(assemblyFile);

                Type[] types = ass.GetExportedTypes();
                foreach (Type type in types)
                {
                    if (type.IsSubclassOf(basetype))
                    {
                        return true;
                    }
                }
            }
            catch
            {
            }

            return false;
        }
	}	
}
